﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using Forms=System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using iText.Kernel.Pdf;
using iText.Kernel.Utils;
using iText.Layout;
using System.Diagnostics;

namespace PdfMerge
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            listBox1.MouseDown += ListBox1_MouseDown;
            listBox1.SelectionChanged += (s, e) =>
            {
                if (listBox1.SelectedIndex != -1)
                    _lastIndex = listBox1.SelectedIndex;
            };

        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Forms.FolderBrowserDialog folderBrowser = new Forms.FolderBrowserDialog();
            
            folderBrowser.Description = "选择要添加的pdf文件路径";

            folderBrowser.ShowNewFolderButton = false;

            if (folderBrowser.ShowDialog() != System.Windows.Forms.DialogResult.OK)
            {
                return;
            }

            string folderPath = folderBrowser.SelectedPath;

            string[] subDirs = Directory.GetDirectories(folderPath);

            List<string> filePaths = new List<string>();

            if (subDirs.Length == 0)
            {
                filePaths = Directory.GetFiles(folderPath).ToList();
            }
            else
            {
                Forms.DialogResult dialogResult = Forms.MessageBox.Show("是否包含子文件夹内的文件", "文件夹内存在子文件夹，", Forms.MessageBoxButtons.YesNo);

                if (dialogResult == Forms.DialogResult.Yes)
                {
                    filePaths = Directory.GetFiles(folderPath, "*.pdf", SearchOption.AllDirectories).ToList();
                }
                if (dialogResult == Forms.DialogResult.No)
                {
                    filePaths = Directory.GetFiles(folderPath).ToList();
                }

            }


            foreach (var item in filePaths)
            {
                string path = item as string;

                if (path != null)
                {
                    if (path.Contains(".pdf"))
                    {

                        List<string> tmpNames = new List<string>();

                        foreach (FileName fnameitem in listBox1.Items)
                        {
                            tmpNames.Add(fnameitem.FullName);
                        }

                        if (tmpNames.Contains(path) == false)
                        {
                            FileName fname = new FileName(path);

                            listBox1.Items.Add(fname);

                        }
                    }
                }
            }

            listBox1.DisplayMemberPath = "FullName";
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            using (var form = new Forms.OpenFileDialog())
            {
                form.Filter = "PDF Files (*.pdf)|*.pdf|All Files (*.*)|*.*";

                form.RestoreDirectory = true;

                form.Title = "Add PDF File(s)";

                form.Multiselect = true;

                if (form.ShowDialog() !=Forms.DialogResult.OK)
                {
                    //Dispose();
                    return;
                }

                string[] fnames = form.FileNames;

                if (fnames.Length == 0)
                {
                    return;
                }

                foreach (string item in fnames)
                {
                    List<string> tmpNames = new List<string>();

                    foreach (FileName fnameitem in listBox1.Items)
                    {
                        tmpNames.Add(fnameitem.FullName);
                    }

                    if (tmpNames.Contains(item) == false)
                    {
                        FileName fName = new FileName(item);

                        listBox1.Items.Add(fName);

                    }

                }
            }

            listBox1.DisplayMemberPath = "FullName";
        }

        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            listBox1.Items.Clear();
        }

        private void Button_Click_3(object sender, RoutedEventArgs e)
        {
            if (listBox1.SelectedIndex > 0)
            {

                int idx = listBox1.SelectedIndex;

                listBox1.Items.Insert(idx - 1, listBox1.SelectedItem);

                listBox1.Items.RemoveAt(idx + 1);

                listBox1.SelectedIndex = idx - 1;



        


            }
        }

        private void Button_Click_4(object sender, RoutedEventArgs e)
        {
            if (listBox1.SelectedIndex < listBox1.Items.Count - 1)
            {
                int idx = listBox1.SelectedIndex;

                listBox1.Items.Insert(idx + 2, listBox1.SelectedItem);

                listBox1.Items.RemoveAt(idx);

                listBox1.SelectedIndex = idx + 1;

                

            }
        }

        private void Button_Click_5(object sender, RoutedEventArgs e)
        {
            try
            {
                if (listBox1.SelectedItem != null)
                {
                    int n = listBox1.SelectedIndex;

                    listBox1.Items.Remove(listBox1.SelectedItem);

                    if (n > 0)
                    {
                        listBox1.SelectedIndex = n - 1;
                    }
                    else
                    {
                        listBox1.SelectedIndex = n;
                    }

                }

            }
            catch (Exception)
            {
                return;
            }
        }

        private void Button_Click_6(object sender, RoutedEventArgs e)
        {
            List<string> pdfNames = new List<string>();

            foreach (FileName item in listBox1.Items)
            {
                pdfNames.Add(item.FullName);
            }

           Forms.SaveFileDialog saveFileDialog1 = new Forms.SaveFileDialog();

            saveFileDialog1.DefaultExt = ".pdf";

            saveFileDialog1.AddExtension = true;

            saveFileDialog1.Filter = "PDF Files (*.pdf)|*.pdf|All Files (*.*)|*.*";

            saveFileDialog1.FilterIndex = 1;

            saveFileDialog1.Title = "合并后文件的名称";

          Forms.DialogResult dialogResult = saveFileDialog1.ShowDialog();

            if (dialogResult ==Forms.DialogResult.OK)
            {

                string obName = saveFileDialog1.FileName;

                bool b = combinePDF(pdfNames, obName);

                if (b)
                {

                    if (!File.Exists(obName)) return;

                    Process.Start(new ProcessStartInfo
                    {
                        FileName = obName,
                        UseShellExecute = true // 必须设为true[5,9](@ref)
                    });



                    MessageBox.Show("程序运行完成。");

                    //FileName fName = new FileName(obName);

                    //listBox1.Items.Add(fName);

                    //listBox1.DisplayMember = "FullName";

                }

            }
        }

        public bool combinePDF(List<string> names, string desFileName)
        {
            bool b = true;
            PdfDocument pdf = new PdfDocument(new PdfWriter(desFileName));
            PdfMerger merger = new PdfMerger(pdf);
            //Add pages from the first document

            foreach (string pdfName in names)
            {
                PdfDocument sourcePdf = new PdfDocument(new PdfReader(pdfName));

                try
                {
                    merger.Merge(sourcePdf, 1, sourcePdf.GetNumberOfPages());

                    sourcePdf.Close();

                }
                catch (Exception)
                {
                    MessageBox.Show("合并:" + pdfName + "时发生错误！");

                    sourcePdf.Close();

                    merger.Close();

                    b = false;

                    break;
                    //throw;
                }

            }

            merger.Close();

            return b;

        }

        private int _lastIndex = -1;

        private void ListBox1_MouseDown(object sender, MouseButtonEventArgs e)
        {

            var item = listBox1.ContainerFromElement((DependencyObject)e.OriginalSource) as ListBoxItem;

            if (item == null) return;

            int index = listBox1.ItemContainerGenerator.IndexFromContainer(item);

            listBox1.SelectedIndex = (index == _lastIndex) ? -1 : index;
        }

        List<FileName> fileNames = new List<FileName>();

        private void ListBox1_Drop(object sender, DragEventArgs e)
        {
            fileNames.Clear();

            Array paths = (System.Array)e.Data.GetData(DataFormats.FileDrop);

            foreach (string item in (System.Array)e.Data.GetData(DataFormats.FileDrop))
            {

                if (System.IO.Directory.Exists(item))
                {

                    DirectoryInfo root = new DirectoryInfo(item);

                    FileInfo[] files = root.GetFiles();

                    foreach (var tmpFileInfo in files)
                    {

                        if (tmpFileInfo.Extension.ToLower().Contains(".pdf"))
                        {

                            FileName fname = new FileName(tmpFileInfo.FullName);

                            if (fileNames.Contains(fname) == false)
                            {
                                fileNames.Add(fname);
                            }

                        }
                    }

                    //文件夹
                }
                else if (System.IO.File.Exists(item))
                {

                    if (item.Contains(".pdf"))
                    {
                        FileName fname = new FileName(item);

                        if (fileNames.Contains(fname) == false)
                        {
                            fileNames.Add(fname);
                        }
                    }

                }

            }

            foreach (var item in fileNames)
            {
                List<string> names = new List<string>();

                foreach (FileName nameitem in listBox1.Items)
                {
                    names.Add(nameitem.FullName);
                }

                if (names.Contains(item.FullName) == false)
                {
                    listBox1.Items.Add(item);
                }

            }

            listBox1.DisplayMemberPath = "FullName";
        }

        private void ListBox1_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
                //e.Effect = DragDropEffects.All;    //重要代码：表明是所有类型的数据，比如文件路径

                e.Effects = DragDropEffects.Link;

            else
                e.Effects = DragDropEffects.None;
        }

        bool sortFlag = true;

        private void Button_Click_7(object sender, RoutedEventArgs e)
        {
            List<FileName> fileNames = new List<FileName>();


            if (listBox1.Items.Count > 1)
            {
                foreach (var item in listBox1.Items)
                {
                    FileName fname = item as FileName;

                    fileNames.Add(fname);
                }

            }

            listBox1.Items.Clear();

            List<FileName> fNames = new List<FileName>();

            if (sortFlag == true)
            {
                var sortedFile = from f in fileNames
                                 orderby f.ShortName
                                 select f;

                fNames = sortedFile.ToList<FileName>();

                sortFlag = false;
            }
            else
            {
                var sortedFile = from f in fileNames
                                 orderby f.ShortName descending
                                 select f;

                fNames = sortedFile.ToList<FileName>();

                sortFlag = true;

            }

            foreach (var item in fNames)
            {
                listBox1.Items.Add(item);

            }

            listBox1.DisplayMemberPath = "FullName";
        }
    }
}
